<template>
  <div>
    <el-container>
      <el-header>
        <!-- 顶部搜索框 -->
        <Search :user-query="userQuery" :options-role="optionsRole" @queryUser="queryUser" />
      </el-header>
      <el-container>
        <!-- 隐藏的侧边树状菜单 -->
        <el-aside v-if="treeVisible" id="draglist" width="200px">
          <el-container>
            <el-header height="30px">
              <p><i class="el-icon-menu" />子系统管理</p>
            </el-header>
            <el-divider />
            <BossSoftTree :data="leftlist" :showcheckbox="false" :showifaccordion="true" />
          </el-container>
        </el-aside>
        <!-- 右侧栏：操作框+主体表格 -->
        <el-main>
          <!-- 按钮操作框 -->
          <el-container>
            <el-header>
              <Operation
                ref="iconArrow"
                @changeArrow="changeArrow"
                @addUsers="addUsers"
                @copyUsers="copyUsers"
                @deleteUsers="deleteUsers"
                @changeStatus="changeStatus"
                @assignRole="assignRole"
              />
            </el-header>
            <!-- 主体表格 -->
            <el-main>
              <MainTable
                ref="userTable"
                :user-table-loading="userTableLoading"
                :table-data="tableData"
                @UpdateCol="UpdateCol"
                @CopyCol="CopyCol"
                @DeleteCol="DeleteCol"
              />
            </el-main>
            <!-- 分页条 -->
            <el-pagination
              :current-page="userPage.pageNum"
              :page-sizes="[10, 20, 30, 40, 50, 100]"
              :page-size="userPage.pageSize"
              layout="total, sizes, prev, pager, next, jumper"
              :total="userPage.total"
              @size-change="handleSizeChange"
              @current-change="handleCurrentChange"
            />
            <!-- 增加弹出框 -->
            <AddDialog
              ref="userInfos"
              :addDialogVisible="addDialogVisible"
              :rules="rules"
              :userInfos="userInfos"
              :optionsDepartment="optionsDepartment"
              :optionsPosition="optionsPosition"
              :optionsRole="optionsRole"
              @closeDialog="closeDialog"
              @addUserOK="addUserOK"
            />
            <!-- 分配角色弹窗 -->
            <el-dialog
              title="用户资源"
              :visible.sync="assigndialogVisible"
              width="60%"
            >
              <el-table
                ref="roleTable"
                :data="roleData"
                tooltip-effect="dark"
                style="width: 100%"
              >
                <el-table-column
                  type="selection"
                  width="55"
                />
                <el-table-column
                  label="序号"
                  width="120"
                  align="center"
                >
                  <template slot-scope="scope">{{ scope.$index + 1 }}</template>
                </el-table-column>
                <el-table-column
                  label="角色名"
                  width="200"
                  align="center"
                >
                  <template slot-scope="scope">{{ scope.row.name }}</template>
                </el-table-column>
                <el-table-column
                  label="角色代码"
                  width="150"
                  align="center"
                >
                  <template slot-scope="scope">{{ scope.row.code }}</template>
                </el-table-column>
                <el-table-column
                  label="角色备注"
                  width="150"
                  align="center"
                >
                  <template slot-scope="scope">{{ scope.row.remark }}</template>
                </el-table-column>
              </el-table>
              <el-pagination
                :current-page="rolePage.pageNum"
                :page-sizes="[10, 20, 30, 40, 50, 100]"
                :page-size="rolePage.pageSize"
                layout="total, sizes, prev, pager, next, jumper"
                :total="rolePage.total"
                @size-change="roleSizeChange"
                @current-change="roleCurrentChange"
              />
              <span slot="footer" class="dialog-footer">
                <el-button @click="assigndialogVisible = false">取 消</el-button>
                <el-button type="primary" @click="assignRoleOK">确 定</el-button>
              </span>
            </el-dialog>
          </el-container>
        </el-main>
      </el-container>
    </el-container>
  </div>
</template>

<script>
import { Message } from 'element-ui'
import BossSoftTree from '@/components/Common/BossSoftTree.vue'
import { commonQuery, queryUserById, add, remove, batchRemove, queryAllRole, queryAllDepartment, queryAllPosition, modify, modifyWithNewRole, batchUpdate } from '@/api/right/user'
import { getResource } from '@/api/right/role'
import Search from './Search.vue'
import MainTable from './MainTable.vue'
import Operation from './Operation.vue'
import AddDialog from './AddDialog.vue'
export default {
  name: 'User',
  components: {
    BossSoftTree,
    Search,
    MainTable,
    Operation,
    AddDialog
  },
  data() {
    return {
      leftlist: [
        {
          label: '角色',
          children: []
        },
        {
          label: '部门',
          children: []
        },
        {
          label: '职位',
          children: []
        }
      ],
      Lwidth: '80px',
      // 加载
      userTableLoading: false,
      // 增加表单校验
      rules: {
        code: [
          { required: true, message: '请输入工号', trigger: 'blur' }
        ],
        name: [
          { required: true, message: '请输入名称', trigger: 'blur' }
        ],
        sex: [
          { required: true, message: '请输入性别', trigger: 'blur' }
        ],
        password: [
          { required: true, message: '请输入密码', trigger: 'blur' }
        ],
        departmentId: [
          { required: true, message: '请选择部门', trigger: 'blur' }
        ],
        positionId: [
          { required: true, message: '请选择职位', trigger: 'blur' }
        ],
        email: [
          { required: true, message: '请输入邮箱号', trigger: 'blur' }
        ],
        tel: [
          { required: true, message: '请输入手机号', trigger: 'blur' },
          {
            pattern: /^((0\d{2,3}-\d{7,8})|(1[3|4|5|7|8][0-9]{9}))$/,
            message: '请输入正确的手机号码或者座机号'
          }
        ],
        roleList: [
          { required: true, message: '请选择角色', trigger: 'blur' }
        ]
      },
      optionsRole: [],
      optionsDepartment: [],
      optionsPosition: [],
      // 提交表单信息
      userInfos: {},
      modifyRoleDTO: [],
      // 点击箭头出现侧边栏
      treeVisible: false,
      // 表单数据
      tableData: [],
      roleData: [],
      // 分页
      userPage: {
        total: null,
        pageNum: 1,
        pageSize: 10,
        pages: null
      },
      rolePage: {
        pageNum: 1,
        pageSize: 10,
        total: null,
        pages: null
      },
      // 用户数据
      userQuery: {
        name: '',
        code: '',
        birthday: '',
        password: '',
        other: '',
        tel: '',
        email: '',
        roleId: '',
        departmentId: '',
        department: {
          name: ''
        },
        positionId: '',
        position: {
          name: ''
        },
        remark: '',
        pageSize: 10,
        pageNum: 1
      },
      // 隐藏元素
      addDialogVisible: false,
      assigndialogVisible: false,
      // 判断是(默认：0)增加(1)、更新(2)、复制(3)
      addtype: 0
    }
  },
  created() {
    this.userTableLoading = true
    this.getTableData(this.userPage.pageSize, 1)
    setTimeout(() => {
      this.userTableLoading = false
    }, 3000)
  },
  mounted() {
    this.addtype = 0
    this.getRoleTable(1)
    this.getAllInfo()
    console.log('tree', this.leftlist)
  },
  methods: {
    /*
     * 获得初始数据
     */
    getAllInfo() {
      queryAllRole()
        .then(res => {
          const { data } = res
          this.optionsRole = data
          this.optionsRole.forEach((item, index) => {
            this.leftlist[0].children[index] = {
              label: item.name
            }
          })
        })
        .catch(() => {
          this.$message.error('网络异常')
        })
      queryAllDepartment()
        .then(res => {
          const { data } = res
          this.optionsDepartment = data
          this.optionsDepartment.forEach((item, index) => {
            this.leftlist[1].children[index] = {
              label: item.name
            }
          })
        })
        .catch(() => {
          this.$message.error('网络异常')
        })
      queryAllPosition()
        .then(res => {
          const { data } = res
          this.optionsPosition = data
          this.optionsPosition.forEach((item, index) => {
            this.leftlist[2].children[index] = {
              label: item.name
            }
          })
        })
        .catch(() => {
          this.$message.error('网络异常')
        })
    },
    /*
    * 获取role表格以及分页功能
    */
    getRoleTable(pageNum) {
      this.rolePage.pageNum = pageNum
      getResource(this.rolePage)
        .then(res => {
          const { total, pages, data } = res
          this.rolePage.total = parseInt(total)
          this.rolePage.pages = parseInt(pages)
          this.roleData = data
        })
        .catch(() => {
          Message({
            message: '加载资源失败',
            type: 'error'
          })
        })
    },
    roleSizeChange(val) {
      this.rolePage.pageSize = val
      this.getRoleTable(this.rolePage.pageNum)
    },
    roleCurrentChange(val) {
      this.rolePage.pageNum = val
      this.getRoleTable(this.rolePage.pageNum)
    },
    /*
     * changeArrow()
     * 功能：打开侧边栏，并更改箭头图标
     */
    changeArrow() {
      this.treeVisible = !this.treeVisible
      if (this.treeVisible) {
        this.$refs.iconArrow.className = 'el-icon-arrow-left'
      } else {
        this.$refs.iconArrow.className = 'el-icon-arrow-right'
      }
    },
    // 当前页改变
    handleCurrentChange(val) {
      // val 当前页面页数
      this.userPage.pageNum = val
      this.getTableData(this.userPage.pageSize, this.userPage.pageNum)
    },
    // 当前页添加或减少新元素
    handleSizeChange(val) {
      // val 当前页面条数
      this.userPage.pageSize = val
      this.getTableData(this.userPage.pageSize, 1)
    },
    // 查询
    queryUser() {
      this.userQuery.departmentId = ''
      this.userQuery.positionId = ''
      this.getTableData(this.userPage.pageSize, 1)
    },
    // 获取主体表格资源
    getTableData(currentPage, pageNum) {
      // console.log('this.userPage.pageSize', this.userPage.pageSize)
      this.userQuery.pageSize = currentPage
      this.userQuery.pageNum = pageNum
      // console.log('this.userQuery', this.userQuery)
      // debugger
      commonQuery(this.userQuery)
        .then((res) => {
          const { total, pageNum, pageSize, data } = res
          this.userPage.total = parseInt(total)
          this.userPage.pageCount = parseInt(pageNum)
          this.userPage.pageSize = parseInt(pageSize)
          this.tableData = data
          this.tableData.forEach((item, index) => {
            if (item.department === undefined) {
              this.tableData[index].department = {
                name: '/'
              }
            } else if (item.position === undefined) {
              this.tableData[index].position = {
                name: '/'
              }
            } else if (item.organization === undefined) {
              this.tableData[index].organization = {
                name: '/'
              }
            } else if (item.company === undefined) {
              this.tableData[index].company = {
                name: '/'
              }
            }
          })
          console.log(this.tableData)
        })
        .catch(() => {
          this.queryLoading = false // 关闭查询
          this.$message.error('网络异常')
        })
    },
    /*
    * 校验表格方法
    * 在增加、更新、复制的时候
    * 主要校验params: code,tel不能重复
    * info: 需要更新的表单对象
    * database: 表格数据库数组
    */
    validateInfo(info, database) {
      let flag = false
      database.forEach((item) => {
        console.log('item.code', item.code)
        console.log('item.code', info.code)
        if (item.code === info.code || item.tel === info.tel) {
          flag = true
          return
        }
      })
      return flag
    },
    closeDialog() {
      this.addDialogVisible = false
      this.$refs.userInfos.$refs.userInfos.resetFields()
    },
    // 增加用户
    addUsers() {
      this.addDialogVisible = true
      this.addtype = 1
    },
    /*
    * 确认增添用户
    * 增加、复制、编辑都需要用到el-tag表
    * 所以使用addtype来判断下一步进行什么 1 增加 2 编辑 3 复制
    * 每一次操作都需要将el-option的id数组转化成数组对象，使用forEach遍历
    */
    addUserOK() {
      this.$refs.userInfos.validate(valid => {
        if (!valid) {
          Message({
            type: 'error',
            message: '提交内容无效'
          })
          return
        } else {
          this.addDialogVisible = false
          if (this.addtype === 1 || this.addtype === 3) {
            const flag = this.validateInfo(this.userInfos, this.tableData)
            console.log('flag', flag)
            if (flag) {
              this.$message.error('手机号或工号重复，请修改！')
            } else {
              this.userInfos.modifier = this.$store.getters.name
              if (this.userInfos.roleList.length !== 0) {
              // 将el-option的id数组转化成数组对象
                const transroleList = []
                this.userInfos.roleList.forEach((item, index) => {
                  transroleList[index] = { id: item }
                })
                this.userInfos.roleList = transroleList
              }
              this.userInfos.id = ''
              const roleDTO = this.userInfos
              console.log('roleDTO', roleDTO)
              add(roleDTO)
                .then((res) => {
                  this.userInfos = []
                  Message({
                    type: 'success',
                    message: '添加成功'
                  })
                  this.userTableLoading = true
                  this.getTableData(this.userPage.pageSize, 1)
                  setTimeout(() => {
                    this.userTableLoading = false
                  }, 3000)
                })
                .catch(() => {
                  Message({
                    type: 'error',
                    message: '添加失败'
                  })
                })
            }
          } else if (this.addtype === 2) {
            console.log('userInfos', this.userInfos)
            this.userInfos.modifier = this.$store.getters.name
            if (this.userInfos.roleList.length !== 0) {
              // 将el-option的id数组转化成数组对象
              const transroleList = []
              this.userInfos.roleList.forEach((item, index) => {
                transroleList[index] = { id: item }
              })
              this.userInfos.roleList = transroleList
            }
            const roleDTO = this.userInfos
            console.log('roleDTO', roleDTO)
            modify(roleDTO)
              .then((res) => {
                this.$message.success('更新成功')
                // 重置
                this.userInfos = []
                this.userTableLoading = true
                this.getTableData(this.userPage.pageSize, 1)
                setTimeout(() => {
                  this.userTableLoading = false
                }, 3000)
              })
              .catch(() => {
                this.$message.error('更新失败！')
              })
          }
        }
      })
    },
    /*
    * 删除单行用户
    * params: (id, version)
    */
    DeleteCol(row) {
      console.log(row)
      this.$confirm('确定删除记录吗', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          remove(row.id, row.version)
            .then(() => {
              this.userTableLoading = true
              this.$message({
                type: 'success',
                message: '删除成功'
              })
              this.getTableData(this.userPage.pageSize, 1)
              setTimeout(() => {
                this.userTableLoading = false
              }, 3000)
            })
            .catch(() => {
              this.$message({
                type: 'error',
                message: '删除失败'
              })
            })
        })
        .catch(() => {
          this.$message({
            type: 'error',
            message: '网络错误'
          })
        })
    },
    /*
    * 批量删除
    * params: 数组对象[{},{},...]
    *         {id:id,version:version}
    */
    deleteUsers() {
      const selectionArray = this.$refs.userTable.$refs.userTable.selection
      if (selectionArray.length === 0) {
        this.$message.error('请选择至少一个用户删除！')
      } else {
        this.$confirm('确定删除吗?')
          .then((res) => {
            const deleteUserDTOS = new Array(selectionArray.length)
            selectionArray.forEach((item, index) => {
              deleteUserDTOS[index] = {
                id: item.id,
                version: item.version
              }
              console.log('deleteUserDTOS', deleteUserDTOS)
              batchRemove(deleteUserDTOS)
                .then(() => {
                  this.userTableLoading = true
                  this.$message({
                    type: 'success',
                    message: '删除成功'
                  })
                  this.getTableData(this.userPage.pageSize, 1)
                  setTimeout(() => {
                    this.userTableLoading = false
                  }, 3000)
                })
                .catch(() => {
                  this.$message.error('删除失败')
                })
            })
          })
          .catch(() => {
            this.$message.error('网络错误')
          })
      }
    },
    /*
    * 更新状况status
    */
    changeStatus(command) {
      switch (command) {
        case 'enable_command': {
          this.changeChoose(1)
          break
        }
        case 'disable_command': {
          this.changeChoose(0)
          break
        }
      }
    },
    changeChoose(status) {
      const selectionArray = this.$refs.userTable.$refs.userTable.selection
      if (selectionArray.length === 0) {
        this.$message.error('请选择至少一条进行操作')
      } else {
        const userDTOS = new Array(selectionArray.length)
        selectionArray.forEach((item, index) => {
          userDTOS[index] = {
            id: item.id,
            status,
            version: item.version
          }
        })
        batchUpdate(userDTOS)
          .then((res) => {
            this.$message.success('操作成功')
            this.userTableLoading = true
            this.getTableData(this.userPage.pageSize, 1)
            setTimeout(() => {
              this.userTableLoading = false
            }, 3000)
          })
          .catch(() => {
            this.$message.error('网络错误')
          })
      }
    },
    /*
     * 更新
     */
    UpdateCol(row) {
      console.log(row)
      this.addDialogVisible = true
      this.addtype = 2
      queryUserById(row.id)
        .then((res) => {
          this.userInfos = res
          this.userInfos.password = ''
          // 将roleList数组对象转化成数组[{}] => []
          this.userInfos.roleList = this.userInfos.roleList.map(item => item.id)
        })
        .catch((err) => {
          this.$message.error(err)
        })
    },
    /*
    * 选择全局复制
    * 复制逻辑跟增加一样。获取信息逻辑跟编辑一样
    */
    copyUsers() {
      const selectionArray = this.$refs.userTable.$refs.userTable.selection
      if (selectionArray.length !== 1) {
        this.$message.error('只能选择一条进行操作！')
      } else {
        // console.log(selectionArray[0].id)
        this.addtype = 3
        this.addDialogVisible = true
        queryUserById(selectionArray[0].id)
          .then((res) => {
            this.userInfos = res
            this.userInfos.password = ''
            // 将roleList数组对象转化成数组[{}] => []
            this.userInfos.roleList = this.userInfos.roleList.map(item => item.id)
          })
          .catch((err) => {
            this.$message.error(err)
          })
      }
    },
    /*
    *单行复制
    */
    CopyCol(row) {
      this.addtype = 3
      this.addDialogVisible = true
      queryUserById(row.id)
        .then((res) => {
          this.userInfos = res
          this.userInfos.password = ''
          // 将roleList数组对象转化成数组[{}] => []
          this.userInfos.roleList = this.userInfos.roleList.map(item => item.id)
        })
        .catch((err) => {
          this.$message.error(err)
        })
    },
    /*
    * 分配角色功能
    */
    assignRole() {
      const selectionArray = this.$refs.userTable.$refs.userTable.selection
      if (selectionArray.length === 0) {
        this.$message.error('只能选择一条进行操作！')
      } else {
        this.assigndialogVisible = true
        const modifyRoleDTO = new Array(selectionArray.length)
        selectionArray.forEach((item, index) => {
          queryUserById(item.id)
            .then((res) => {
              this.userInfos = res
              // 将roleList数组对象转化成数组[{}] => []
              this.userInfos.roleList = this.userInfos.roleList.map(item => item.id)
              console.log('userInfos', this.userInfos)
              modifyRoleDTO[index] = this.userInfos
              console.log('modifyRoleDTO', modifyRoleDTO)
              this.userInfos = {}
            })
            .catch(() => {
              this.$message.error('网络错误')
            })
        })
        console.log(modifyRoleDTO)
        this.modifyRoleDTO = modifyRoleDTO
      }
    },
    /*
    * 成功分配
    */
    assignRoleOK() {
      this.assigndialogVisible = false
      const selectionArray = this.$refs.roleTable.selection
      if (selectionArray.length === 0) {
        this.$message.error('请选择至少一个角色进行分配')
      }
      console.log('selectionArray', selectionArray)
      console.log('thisroleDOT', this.modifyRoleDTO)
      const transroleList = []
      selectionArray.forEach((item, index) => {
        transroleList[index] = { id: item.id }
      })
      this.modifyRoleDTO.forEach(item => {
        item.roleList = transroleList
      })
      modifyWithNewRole(this.modifyRoleDTO)
        .then(() => {
          this.$message.success('分配成功！')
        })
        .catch(() => {
          this.$message.error('网络错误！')
        })
        .finally(() => {
          this.modifyRoleDTO = []
          this.getTableData(this.userPage.pageSize, 1)
        })
    }
  }
}
</script>

<style scoped>
  .el-icon-arrow-down {
    font-size: 12px;
  }
  #draglist{
    margin-left:10px;
    border:1px solid rgb(223, 216, 216);
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
   }
</style>
